﻿using System;
using System.Web.UI.WebControls;
using System.Web;
using System.Web.UI;
using System.Security.Permissions;
using System.ComponentModel;
using System.IO;

namespace Tal.CaptchaControl

{
    [
    AspNetHostingPermission(SecurityAction.Demand,
        Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand,
        Level = AspNetHostingPermissionLevel.Minimal),
    DefaultProperty("Text"),
    ToolboxData("<{0}:CaptchaControl runat=\"server\"> </{0}:CaptchaControl>")
    ]

    public partial class CaptchaControl:WebControl
    {
        private void CreateScript()
        {
            if (Path.IsPathRooted(this.RengerateScriptName))
            {
                this.ajaxScriptName = this.RengerateScriptName;
            }
            else
            {
                this.ajaxScriptName =HttpContext.Current.Request.MapPath(this.RengerateScriptName);
            }

            if (!File.Exists(this.ajaxScriptName))
            {
                File.WriteAllText(this.ajaxScriptName, "<%@ Page Language=\"C#\" %>\r\n" +
    "<script runat=\"server\">\r\n" +
        "protected void Page_Init(object sender, EventArgs e)\r\n" +
        "{\r\n" +
            "if (Request.QueryString[\"actionName\"]==\"Regenerate\")\r\n{" +
            "if (Session[\"captchaCharactersTypes\"] != null)"+
            "{"+
                "TextGenerator tg=new SixCharsTextGenerator();"+
                "string text=tg.Generate((TextGenerator.CharacterType)Session[\"captchaCharactersTypes\"]);"+
                "string path=Tal.CaptchaControl.ImageManager.WriteImage(text);"+
                "Session[\"captcha_image_text\"] = text;"+
                "Response.Write(path);"+
                "Response.End();"+
            "}"+
            "}" +
        "}\r\n" +
    "</script>\r\n");
                //            Cache.Add(FullPath,
                //                FileName,i
                //                null,
                //                System.Web.Caching.Cache.NoAbsoluteExpiration,
                //                TimeSpan.FromMinutes(20),
                //                System.Web.Caching.CacheItemPriority.High,
                //                new System.Web.Caching.CacheItemRemovedCallback(CacheItemRemoved));
            }
        }

        private string ajaxScriptName;

        /// <summary>
        /// Gets a value indicating whether the answer text received from 
        /// the user is equal to the session value
        /// </summary>
        public bool IsValid
        {
            get
            {
                if (HttpContext.Current != null && HttpContext.Current.Session != null)
                {
                    if (oldSessionText == null)
                    {
                        oldSessionText = HttpContext.Current.Session["captcha_image_text"] as string;
                    }
                    if (oldSessionText != null)
                    {
                        TextBox txt = this.FindControl("txtAnswer") as TextBox;
                        if (txt != null)
                        {

                            return string.Compare(txt.Text,
                                oldSessionText,
                                this.IgnoreCase) == 0;
                        }
                    }
                }
                return false;
            }
        }


        protected override void CreateChildControls()
        {

            Label lblText = new Label();
            lblText.Text = this.Text;
            lblText.ID = "lblText";
            lblText.EnableViewState = false;
            this.Controls.Add(lblText);
            TextBox txtAnswer = new TextBox();
            txtAnswer.ID = "txtAnswer";
       //     txtAnswer.EnableViewState = false;
            this.Controls.Add(txtAnswer);
            System.Web.UI.WebControls.Image img = new System.Web.UI.WebControls.Image();
            img.ID = "imgCaptcha";

            img.AlternateText = "captcha text";
            this.Controls.Add(img);
            Label lblError = new Label();
            lblError.ID = "lblError";
            lblError.EnableViewState = false;
            lblError.Visible = false;
            lblError.Text = this.ErrorMessage;
            this.Controls.Add(lblError);
            if (EnableRegenarateImage)
            {
                LinkButton lbRegenerate = new LinkButton();

                lbRegenerate.OnClientClick = "return GetAjax('" + this.RengerateScriptName +
                    "?actionName=Regenerate','" + img.ClientID + "');";
                lbRegenerate.ID = "lbRegenerate";
                lbRegenerate.Text = this.RegenarateImageText;
                this.Controls.Add(lbRegenerate);
            }
        }

        protected override void RenderChildren(HtmlTextWriter writer)
        {
            if (!Directory.Exists(ImagesPhisicalPath))
            {
                Directory.CreateDirectory(ImagesPhisicalPath);
            }
            WriteImage();//write the image to file
            SetSessionText();//set the text in session
            writer.AddAttribute(HtmlTextWriterAttribute.Width, "100%");
            writer.RenderBeginTag(HtmlTextWriterTag.Table);
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            this.FindControl("lblText").RenderControl(writer);
            writer.RenderEndTag();
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            TextBox txtAnswer =(TextBox) this.FindControl("txtAnswer");
            txtAnswer.RenderControl(writer);
            writer.RenderEndTag();
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            Image img = (Image)this.FindControl("imgCaptcha");
            img.ImageUrl = "http://" +HttpContext.Current.Request.Url.Authority +HttpContext.Current.Request.ApplicationPath + "/" + this.FileName;
            img.RenderControl(writer);
            writer.RenderEndTag();
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            this.FindControl("lblError").RenderControl(writer);
            writer.RenderEndTag();
            if (EnableRegenarateImage)
            {
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this.FindControl("lbRegenerate").RenderControl(writer);
                writer.RenderEndTag();
            }
            writer.RenderEndTag();//tr
            writer.RenderEndTag();//table

        }
        
        protected override ControlCollection CreateControlCollection()
        {
            return base.CreateControlCollection();
        }
        public override void RenderControl(HtmlTextWriter writer)
        {
            RenderChildren(writer);
            writer.Write(@"<script type=""text/javascript"">
        function GetAjax(url, id) {
        var myAjax;
        try { myAjax = new ActiveXObject('Msxml2.XMLHTTP'); }
        catch (e)
        {
            try { myAjax = new ActiveXObject('Microsoft.XMLHTTP'); }
            catch (e2)
                {
                    try { myAjax = new XMLHttpRequest(); }
                    catch (e3) { alert('could not create ajax object');return; }
                }
        }
        myAjax.onreadystatechange = function() {
            if (myAjax.readyState == 4) {
                if (myAjax.status == 200) {
                    hasError = false;
                    ajaxResponse = myAjax.responseText;
                }
                else {
                    hasError = true;
                    ajaxResponse = 'Error ' + myAjax.status;
                }
                document.getElementById(id).src = ajaxResponse;
            }
        };
        myAjax.open('POST', url, true);
        myAjax.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        myAjax.setRequestHeader('Connection', 'close');
        myAjax.send('');
        return false;
    } 
</script>");
        }
       
        private string oldSessionText;
        private void SetSessionText()
        {
            if (HttpContext.Current != null)
            {
                if (HttpContext.Current.Session != null)
                {
                    if (HttpContext.Current.Session["captcha_image_text"] != null)
                    {
                        oldSessionText = (string)HttpContext.Current.Session["captcha_image_text"];//save for after the post back
                    }
                    HttpContext.Current.Session["captcha_image_text"] = ImageText;
                }
            }
        }
        
    }
}
